package com.xfpp.javaDemo.proxy;

import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;

public class Proxy {
	public static Object newProxyInstance(Class infce, InvocationHandler h) throws Exception{
		Method[] methods = infce.getMethods();
		String methodStr = ""; //方法字符串拼接
		String ln = "\r\t"; //换行符
		String className = "$Proxy1";
		/*for (Method method : methods) {
			methodStr += 
			"	@Override" + ln +
			"	public void "+method.getName()+"() {" + ln +
			"		long start = System.currentTimeMillis();" + ln +
			"		System.out.println(\"start time : \" + start);" + ln +
			"		t."+method.getName()+"();" + ln +
			"		long end = System.currentTimeMillis();" + ln +
			"		System.out.println(\"调用此方法消耗的时间是：\" + (end - start) );" + ln +
			"	}" + ln;
		}*/
		for (Method method : methods) {
			methodStr += 
					ln +
					"	@Override" + ln +
					"	public void "+method.getName()+"() {" + ln +
					"        try {"+ ln +
					"        	Method md = "+ infce.getName() + ".class.getMethod(\""+method.getName()+"\");" + ln +
					"        	h.invoke(this, md);"+ ln +
					"        }catch(Exception e) {"+ ln +
					"        	e.printStackTrace();"+ ln +
					"        }"+ ln +
					"	}" + ln;
		}
		
		String src = 
			"package com.xfpp.javaDemo.proxy;" + ln +
			"import java.lang.reflect.Method;" + ln +

			"public class "+ className +" implements "+ infce.getName() + "{" + ln +
	//		"	private Moveable t;" + ln +
			"	private com.xfpp.javaDemo.proxy.InvocationHandler h;" + ln +
				
			"	public "+ className +"(InvocationHandler h) {"+ ln +
			"		super();" + ln +
			"		this.h = h;" + ln +
			"	}" + ln +
			
			/*"	@Override" + ln +
			"	public void move() {" + ln +
			"		long start = System.currentTimeMillis();" + ln +
			"		System.out.println(\"start time : \" + start);" + ln +
			"		t.move();" + ln +
			"		long end = System.currentTimeMillis();" + ln +
			"		System.out.println(\"调用此方法消耗的时间是：\" + (end - start) );" + ln +
			"	}" + ln +*/
			methodStr +
	
			"}";
		
		String fileName = "E:/src/com/xfpp/javaDemo/proxy/"+ className +".java";
		File f = new File(fileName);
		FileWriter fw = new FileWriter(f);
		fw.write(src);
		fw.flush();
		fw.close();
		
		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
//		System.out.println(compile.getClass().getName());
		StandardJavaFileManager sjfm = compiler.getStandardFileManager(null, null, null);
		Iterable units = sjfm.getJavaFileObjects(fileName);
		CompilationTask ct = compiler.getTask(null, sjfm, null, null, null, units);
		ct.call();
		sjfm.close();
		
		URL[] urls = new URL[]{new URL("file:/E:/src/")};
		URLClassLoader ul = new URLClassLoader(urls);
		Class c = ul.loadClass("com.xfpp.javaDemo.proxy."+ className);
		
		Constructor ctr = c.getConstructor(InvocationHandler.class);
		Object m = (Object)ctr.newInstance(h);
//		m.move();
		
		return m;
	}
}
